import Skeleton, { SkeletonTheme } from "react-loading-skeleton"; import { ChevronDownIcon, ClockIcon, HeartIcon, } from "@heroicons/react/20/solid"; import { TvIcon, ArrowTrendingUpIcon, RectangleStackIcon, } from "@heroicons/react/24/outline"; import Head from "next/head"; import Image from "next/image"; import { useRouter } from "next/router"; import { useEffect, useRef, useState } from "react"; import Layout from "../../../components/layout"; import Link from "next/link"; import Content from "../../../components/home/content"; import Modal from "../../../components/modal"; import { signIn, useSession } from "next-auth/react"; import AniList from "../../../components/media/aniList"; import ListEditor from "../../../components/listEditor"; import { GET_MEDIA_USER } from "../../../queries"; import { GET_MEDIA_INFO } from "../../../queries"; import { closestMatch } from "closest-match"; // import { aniInfo } from "../../components/devComp/data"; // console.log(GET_MEDIA_USER); export default function Info({ info, color, api }) { // Episodes dropdown const [firstEpisodeIndex, setFirstEpisodeIndex] = useState(0); const [lastEpisodeIndex, setLastEpisodeIndex] = useState(); const [selectedRange, setSelectedRange] = useState("All"); function onEpisodeIndexChange(e) { if (e.target.value === "All") { setFirstEpisodeIndex(0); setLastEpisodeIndex(); setSelectedRange("All"); return; } setFirstEpisodeIndex(e.target.value.split("-")[0] - 1); setLastEpisodeIndex(e.target.value.split("-")[1]); setSelectedRange(e.target.value); } const { data: session } = useSession(); const [episode, setEpisode] = useState(null); const [loading, setLoading] = useState(false); const [progress, setProgress] = useState(0); const [statuses, setStatuses] = useState(null); const [domainUrl, setDomainUrl] = useState(""); const [showAll, setShowAll] = useState(false); const [visible, setVisible] = useState(false); const [open, setOpen] = useState(false); const [time, setTime] = useState(0); const { id } = useRouter().query; const [fetchFailed, setFetchFailed] = useState(false); const failedAttempts = useRef(0); const [artStorage, setArtStorage] = useState(null); const rec = info?.recommendations?.nodes?.map( (data) => data.mediaRecommendation ); const [log, setLog] = useState(); //for episodes dropdown useEffect(() => { setFirstEpisodeIndex(0); setLastEpisodeIndex(); setSelectedRange("All"); }, [info]); useEffect(() => { handleClose(); async function fetchData() { setLoading(true); if (id) { const { protocol, host } = window.location; const url = `${protocol}//${host}`; setDomainUrl(url); setArtStorage(JSON.parse(localStorage.getItem("artplayer_settings"))); setEpisode(null); setProgress(0); setStatuses(null); try { const res1 = await Promise.race([ fetch( `https://ani-indo.vercel.app/get/search?q=${encodeURIComponent( info.title.romaji )}` ), new Promise((_, reject) => setTimeout(() => reject(new Error("timeout")), 10000) ), ]); const data1 = await res1.json(); if (data1.data.length === 0) { let text = info.title.romaji; let words = text.split(" "); let firstTwoWords = words.slice(0, 2).join(" "); setLog(firstTwoWords); const anotherRes = await Promise.race([ fetch( `https://ani-indo.vercel.app/get/search?q=${firstTwoWords}` ), new Promise((_, reject) => setTimeout(() => reject(new Error("timeout")), 10000) ), ]); const fallbackData = await anotherRes.json(); const title = fallbackData.data.map((i) => i.title); const match = closestMatch(info.title.romaji, title); if (match) { const getAnime = fallbackData.data.find((i) => i.title === match); const res2 = await fetch( `https://ani-indo.vercel.app/get/info/${getAnime.animeId}` ); const data2 = await res2.json(); if (data2.status === "success") { setEpisode(data2.data[0].episode); } // setLog(data2); } else { setLoading(false); } } if (data1.status === "success") { const title = data1.data.map((i) => i.title); const match = closestMatch(info.title.romaji, title); if (match) { const getAnime = data1.data.find((i) => i.title === match); const res2 = await fetch( `https://ani-indo.vercel.app/get/info/${getAnime.animeId}` ); const data2 = await res2.json(); if (data2.status === "success") { setEpisode(data2.data[0].episode); } // setLog(data2); } else { setLoading(false); } // setLog(match); } // setLog(data1); if (session?.user?.name) { const response = await fetch("https://graphql.anilist.co/", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ query: GET_MEDIA_USER, variables: { username: session?.user?.name, }, }), }); const responseData = await response.json(); const prog = responseData?.data?.MediaListCollection; if (prog && prog.lists.length > 0) { const gut = prog.lists .flatMap((item) => item.entries) .find((item) => item.mediaId === parseInt(id[0])); if (gut) { setProgress(gut.progress); const statusMapping = { CURRENT: { name: "Watching", value: "CURRENT" }, PLANNING: { name: "Plan to watch", value: "PLANNING" }, COMPLETED: { name: "Completed", value: "COMPLETED" }, DROPPED: { name: "Dropped", value: "DROPPED" }, PAUSED: { name: "Paused", value: "PAUSED" }, REPEATING: { name: "Rewatching", value: "REPEATING" }, }; setStatuses(statusMapping[gut.status]); } } setLoading(false); } if (info.nextAiringEpisode) { setTime( convertSecondsToTime(info.nextAiringEpisode.timeUntilAiring) ); } } catch (error) { if (error.message === "timeout") { const currentAttempts = parseInt(localStorage.getItem("failedAttempts") || "0", 10) + 1; localStorage.setItem("failedAttempts", currentAttempts.toString()); if (currentAttempts < 3) { window.location.reload(); } else { localStorage.removeItem("failedAttempts"); setFetchFailed(true); } } else { console.error(error); } } } setLoading(false); } fetchData(); }, [id, info, session?.user?.name]); function handleOpen() { setOpen(true); document.body.style.overflow = "hidden"; } function handleClose() { setOpen(false); document.body.style.overflow = "auto"; } return ( <>
Episodes
{epi.epsTitle}
{index !== episode?.length - 1 && ( )}No Episodes Available
)}
{episode?.message || "Anime tidak tersedia :/"}